home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c++-part2 / 14365 < prev    next >
Encoding:
Internet Message Format  |  1996-08-05  |  4.2 KB

  1. Path: linus.mitre.org!spectre!eachus
  2. From: eachus@spectre.mitre.org (Robert I. Eachus)
  3. Newsgroups: comp.lang.ada,comp.lang.c++
  4. Subject: Iterators (was Re: some questions re. Ada/GNAT from a C++/GCC user)
  5. Date: 30 Mar 1996 00:11:46 GMT
  6. Organization: The Mitre Corp., Bedford, MA.
  7. Message-ID: <EACHUS.96Mar29191146@spectre.mitre.org>
  8. References: <wnewmanDoxrCp.DKv@netcom.com> <Dp1oAw.7Cz@world.std.com>
  9. NNTP-Posting-Host: spectre.mitre.org
  10. In-reply-to: bobduff@world.std.com's message of Fri, 29 Mar 1996 19:47:20 GMT
  11.  
  12. In article <Dp1oAw.7Cz@world.std.com> bobduff@world.std.com (Robert A Duff) writes:
  13.  
  14.   > > Is there any way in Ada to iterate abstractly over the contents of a 
  15.   > > container,...
  16.  
  17.   > Several ways:
  18.  
  19.   >     - Write a generic procedure Iterate, which takes a formal
  20.   >     procedure representing the body of the loop -- that is,
  21.   >     the formal procedure says what to do for each element.
  22.  
  23.   Funny you should mention it...  Right now I have two projects where
  24. I am dealing with a large mass (1000s) of source files.  I need to run
  25. some tools over the code.  The choice was between Ada and a shell
  26. script...I chose Ada:
  27.  
  28. generic
  29.   with procedure To_Do(File: in String);
  30. procedure Iterate_Files(Pattern: in String := "*";
  31.                         Directory: in String := "");
  32. -- This generic iterates over all files in a directory matching Pattern and
  33. -- calls To_Do once for each such directory entry.  If a file has several
  34. -- links in the directory To_Do will be called once for each.
  35.  
  36.   (The body for SunAda/VADS is tacked on at the end of this
  37. message. It isn't all that complex. If someone wants to rewrite for
  38. GNAT and post, feel free, but there may be a lot of GNAT versions
  39. needed,  I don't know if it is possible to share code between
  40. different operating systems.)
  41.  
  42.    Two observations.  First, the generic procedure approach is
  43. certainly right for this case.  Second, the VADS run-time provided a
  44. call for freeing A_Strings, but not for find_files.find_file_rec, so I
  45. put in the call for the A_Strings case only.  If I felt that there
  46. would be hundreds of calls with different patterns, I probably would
  47. have gone through the pain of "fixing" the find_files package by
  48. adding the missing functionality.  But in my case, the one call to
  49. A_Strings.Free(Next) is enough garbage collection for all practical
  50. purposes...the call in the exception handler is for style more than
  51. anything else.
  52.  
  53.     And I know that this is something I have said before, but this
  54. particular example is a good one.  The primary argument in favor of
  55. compilers which support general garbage collection is that the end
  56. user shouldn't have to worry about garbage collection.  But in this
  57. example 1) the user of the package sees no garbage ever and 2)
  58. managing memory "right" was an extremely small effort when writing the
  59. generic.  Even if all Ada compilers had generalized garbage
  60. collectors, the right choice here would be to build a procedure which
  61. predictably cleaned up after itself rather than warning the user that
  62. there would be lots of garbage generated which might affect global
  63. performance.
  64.  
  65.  
  66.                     Robert I. Eachus
  67.  
  68. with Standard_Disclaimer;
  69. use  Standard_Disclaimer;
  70. function Message (Text: in Clever_Ideas) return Better_Ideas is...
  71.  
  72.  
  73. ----------------------------------------------------------------------------
  74. -- generic
  75. --   with procedure To_Do(File: in String);
  76. with A_Strings;
  77. with File_Names;
  78. procedure Iterate_Files(Pattern: in String := "*";
  79.                         Directory: in String := "") is
  80.   Pat: A_Strings.A_String;
  81.   Handle: File_Names.Find_File_Info;
  82.   Next: A_Strings.A_String;
  83. begin
  84.  
  85.   if Directory = "" 
  86.   then Pat := A_Strings.To_A(Pattern);
  87.   else Pat := A_Strings.To_A(Directory & "/" & Pattern);
  88.   end if;
  89.  
  90.   Handle := File_Names.Init_Find_File(Pat);
  91.   loop
  92.      Next := File_Names.Find_File(Handle);
  93.      if Directory = "" and then Next.s(1..2) = "./"
  94.      then To_Do(Next.s(3..Next.len));
  95.      else To_Do(Next.s);
  96.      end if;
  97.      A_Strings.Free(Next);
  98.   end loop;
  99. exception
  100.   when File_Names.No_More_Files => A_Strings.Free(Pat);
  101. end Iterate_Files;
  102.  
  103. -----------------------------------------------------------------------------
  104. --
  105.  
  106.                     Robert I. Eachus
  107.  
  108. with Standard_Disclaimer;
  109. use  Standard_Disclaimer;
  110. function Message (Text: in Clever_Ideas) return Better_Ideas is...
  111.